package com.atguigu.tingshu.account.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.tingshu.account.mapper.RechargeInfoMapper;
import com.atguigu.tingshu.account.mapper.UserAccountMapper;
import com.atguigu.tingshu.account.service.RechargeInfoService;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.account.RechargeInfo;
import com.atguigu.tingshu.model.account.UserAccount;
import com.atguigu.tingshu.vo.account.RechargeInfoVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.concurrent.TimeUnit;

@Service
public class RechargeInfoServiceImpl extends ServiceImpl<RechargeInfoMapper, RechargeInfo> implements RechargeInfoService {

	@Autowired
	private RechargeInfoMapper rechargeInfoMapper;

	@Autowired
	private UserAccountMapper userAccountMapper;

	@Autowired
	private RedisTemplate redisTemplate;

	@Autowired
	private RabbitTemplate rabbitTemplate;

	@Autowired
	private RedissonClient redissonClient ;


	@Override
	public Object submitRecharge(RechargeInfoVo rechargeInfoVo) {
		if (rechargeInfoVo == null){
			throw new GuiguException(201,"参数错误");
		}
		//获取充值的金额
		int amount = rechargeInfoVo.getAmount().intValue();
		if (amount < 0){
			throw new GuiguException(201,"充值金额错误");
		}
		JSONObject result = new JSONObject();
		if (redisTemplate.opsForValue().setIfAbsent("amount_payment_lock"+ AuthContextHolder.getUserId(),"1",60*1000,TimeUnit.MILLISECONDS)){
			try {
				UserAccount userAccount = userAccountMapper.selectOne(new LambdaQueryWrapper<UserAccount>().eq(UserAccount::getUserId, AuthContextHolder.getUserId()));
				BigDecimal availableAmount = userAccount.getAvailableAmount();
				//限制账户总金额为200
				//充值金额 + 账户余额 不能 大于 200
				if (amount + availableAmount.intValue() > 200) {
					throw new GuiguException(201, "账户金额不能超过200");
				}
				//修改充值信息
				RechargeInfo rechargeInfo = new RechargeInfo();
				rechargeInfo.setUserId(AuthContextHolder.getUserId());
				rechargeInfo.setOrderNo(IdWorker.get32UUID());
				rechargeInfo.setRechargeStatus("0901");//未支付
				rechargeInfo.setRechargeAmount(new BigDecimal(amount));
				rechargeInfo.setPayWay("1101");//微信支付
				save(rechargeInfo);

				result.put("orderNo", rechargeInfo.getOrderNo());

				//TODO-> 使用延迟消息队列，设置订单超时取消
				rabbitTemplate.convertAndSend("account_recharge_delay_exchange",
						"account.recharge.dead",
						rechargeInfo.getOrderNo()+":"+rechargeInfo.getUserId(),
						message -> {
							MessageProperties messageProperties = message.getMessageProperties();
							messageProperties.setExpiration("6000");
							return message;
						});
				return result;
			}catch(Exception e){
				//业务流程错误,删除锁
				redisTemplate.delete("amount_payment_lock"+ AuthContextHolder.getUserId());
				throw e;
			}

		}

		throw new GuiguException(201,"有一笔未支付充值订单");
	}

	/**
	 * 主动取消/超时取消订单
	 * @param orderNo
	 */
	@Override
	public void cancleRechargeInfo(String orderNo) {
		//默认为主动取消
		String rechargeStatus = "0903";
		boolean flag = false;

		//如果本地线程为null，说明是超时取消
		Long userId = AuthContextHolder.getUserId();

		if (userId ==null){
			//设置为超时取消
			rechargeStatus = "0904";
			String[] split = orderNo.split(":");
			//获取用户id
			userId = Long.valueOf(split[1]);
			//获取订单号
			orderNo = split[0];
		}
		else {
			flag = true;
		}

		//加锁
		RLock lock = redissonClient.getLock("Recharge_Info_Pay_lock" + orderNo + "UserId" + userId);
		if (lock.tryLock()){
			try {
				//查询订单记录
				RechargeInfo rechargeInfo = getOne(new LambdaQueryWrapper<RechargeInfo>()
						.eq(RechargeInfo::getUserId, userId)
						.eq(RechargeInfo::getOrderNo, orderNo)
						.eq(RechargeInfo::getRechargeStatus, "0901"));
				if (rechargeInfo != null){
					//设置为超时取消
					rechargeInfo.setRechargeStatus(rechargeStatus);
					updateById(rechargeInfo);
				}
			}catch (Exception e){
				throw e;
			}finally {
				lock.unlock();
				//主动取消，主动删除Redis的锁
				redisTemplate.delete("amount_payment_lock" + AuthContextHolder.getUserId());
			}
		}
	}

	/**
	 * 获取支付地址
	 * @param orderNo
	 * @return
	 */
	@Override
	public Object getRechargePayInfo(String orderNo) {
		if (orderNo == null){
			throw new GuiguException(201,"参数错误");
		}
		return null;
	}
}
